#pragma once

#include <wx/wx.h>

#define CYGWIN_INSTALLED_DB_PATH _T("/etc/setup/installed.db")
#define CYGWIN_INSTALLED_LST_DIR _T("/etc/setup/")

struct PkgInfo {
	PkgInfo() {
	    source_status = AVAILABLE;
	    binary_status = AVAILABLE;
	}
	
	enum STATUS {
		INVALIDE = -1,
		AVAILABLE = 0,
		UPDATED,
		OUTDATED,
		// actions
		XINSTALL,
		REINSTALL,
		UPGRADE,
		REMOVE,
		PURGE,
	};
	
	wxString name;
	wxString sdesc;
	wxString ldesc;
    wxString version;
    wxArrayString category;
    wxArrayString require;
    wxArrayString dependent;
    
    wxString binary_path;
    wxString binary_size;
    wxString binary_md5;

    wxString source_path;
    wxString source_size;
    wxString source_md5;
    
    STATUS source_status;
    STATUS binary_status;
};

struct InstalledInfo {
	wxString name;
    wxString binary_version;
    wxString binary_path;
    wxString source_path;
    wxString source_version;
};

struct CatInfo {
	wxString name;
	wxArrayString pkg_names;
};


WX_DECLARE_STRING_HASH_MAP(PkgInfo, PkgHash);
WX_DECLARE_STRING_HASH_MAP(InstalledInfo, InstalledHash);
WX_DECLARE_STRING_HASH_MAP(CatInfo, CategoryHash);


class InstalledBuilder {
public:
	static InstalledBuilder& get() {
		return self;
	}
	
	virtual ~InstalledBuilder();
	
	bool parse_db(/* const wxString& path */);
	
	bool save_db();
	
	wxArrayString& get_pkgs() {
		return _packages;
	}
	
	wxArrayString get_installed_files(const wxString& pkg);
	
	enum _STATUS {
		NOT_INSTALLED = 0x00,
		BINARY_INSTALLED = 0x01,
		SOURCE_INSTALLED = 0x02,
		BOTH_INSTALLED = 0x03,
		BINARY_UPGRADABLE = 0x04,
		SOURCE_UPGRADABLE = 0x08,
		BOTH_UPGRADABLE = 0x012,
	};
	// int is_installed(const wxString& name);
	
	wxString get_version(const wxString& name) {
		if (_installed_hash.find(name) == _installed_hash.end() ) {
			return wxString();
		}
		
		return _installed_hash[name].binary_version;
	}
	
	wxString get_src_version(const wxString& name) {
		if (_installed_hash.find(name) == _installed_hash.end() ) {
			return wxString();
		}
		
		return _installed_hash[name].source_version;
	}
	
protected:
	InstalledBuilder();
	
	static InstalledBuilder self;
	
	InstalledHash _installed_hash;
	wxArrayString _packages;
};
